@typeparam TItem
@using System.Globalization
@{
    var rowArgs = Grid?.GroupRowAttributes(this);

    if (Grid != null)
    {
        if (rowArgs.Item1.Expanded == true && Grid.collapsedGroupItems.ContainsKey(this))
        {
            Grid.collapsedGroupItems.Remove(this);
        }
    }
}
<tr class="rz-group-row" @attributes="@rowArgs.Item2">
    @if (Grid.ShowGroupExpandColumn)
    {
        @if (Group.GroupDescriptor != null)
        {
            @for (var i = 0; i < GetLevel(); i++)
            {
                <td class="rz-col-icon">
                    <span class="rz-column-title"></span>
                </td>
            }

        }
        <td class="rz-col-icon">
            <span class="rz-column-title"></span>
            <a id="@(Grid.GridId() + Group.GetHashCode())" aria-label=@Grid.ExpandGroupAriaLabel @onclick:preventDefault="true" @onclick="@(_ => Grid.ExpandGroupItem(this, rowArgs.Item1.Expanded))">
                <span class="@(Grid.ExpandedGroupItemStyle(this, Grid.allGroupsExpanded != null ? Grid.allGroupsExpanded : rowArgs.Item1.Expanded))"></span>
            </a>
        </td>
    }
    <td colspan="@(TotalColumnCount + Grid.Groups.Count - 1 - Group.Level + (Grid.Template != null && Grid.ShowExpandColumn ? 1 : 0))">
        <span class="rz-cell-data">
            @if (Grid.GroupHeaderTemplate != null)
            {
                @Grid.GroupHeaderTemplate(Group)
            }
            else if (Grid.GroupHeaderToggleTemplate != null)
            {
                @Grid.GroupHeaderToggleTemplate((Group, this))
            }
            else if(Group.GroupDescriptor != null)
            {
                @(Group.GroupDescriptor.GetTitle() + ": " + GetKeyAsString())
            }
        </span>
    </td>
</tr>
@if(Grid != null)
{
    if (Grid.IsGroupItemExpanded(this) && rowArgs.Item1.Expanded != false && Grid.allGroupsExpanded != false)
    {
        @DrawDataRows()
    }
    else if(Grid.GroupFootersAlwaysVisible)
    {
        if (!Grid.collapsedGroupItems.Keys.Contains(this))
        {
            Grid.collapsedGroupItems.Add(this, true);
        }

        @DrawDataRows(true)
    }
    else
    {
        if (!Grid.collapsedGroupItems.Keys.Contains(this))
        {
            Grid.collapsedGroupItems.Add(this, true);
        }
    }
}
@code {
    string GetKeyAsString()
    {
        var value = !string.IsNullOrEmpty(Group.GroupDescriptor.FormatString) ?
            string.Format(Grid?.Culture ?? CultureInfo.CurrentCulture, Group.GroupDescriptor.FormatString, Group.Data.Key) :
                Convert.ToString(Group.Data.Key, Grid?.Culture ?? CultureInfo.CurrentCulture);
        return $"{value}";
    }

    [Parameter]
    public IList<RadzenDataGridColumn<TItem>> Columns { get; set; }

    GroupResult _groupResult;
    [Parameter]
    public GroupResult GroupResult
    {
        get
        {
            return _groupResult;
        }
        set
        {
            if(_groupResult != value)
            {
                _groupResult = value;

                var level = GetLevel();
                Group = new Group()
                {
                    Level = level,
                    GroupDescriptor = Grid.Groups?.ElementAtOrDefault(level),
                    Data = _groupResult
                };
            }
        }
    }


    private int TotalColumnCount
    {
        get
        {
            var columnsOfGrid = Columns
                  .Where(c => c.GetVisible())
                  .ToList();
            return columnsOfGrid.Sum(c => CountVisibleLeafColumns<TItem>(c));
        }
    }

    [Parameter]
    public RadzenDataGrid<TItem> Grid { get; set; }

    [Parameter]
    public RadzenDataGridGroupRow<TItem> Parent { get; set; }

    [Parameter]
    public Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder Builder { get; set; }

    RenderFragment DrawDataRows(bool groupFootersOnly = false)
    {
        return new RenderFragment(builder =>
        {
            if(GroupResult.Subgroups != null)
            {
                foreach(var g in GroupResult.Subgroups)
                {
                    builder.OpenComponent(0, typeof(RadzenDataGridGroupRow<TItem>));
                    builder.AddAttribute(1, "Columns", Columns);
                    builder.AddAttribute(3, "Grid", Grid);
                    builder.AddAttribute(3, "Parent", this);
                    builder.AddAttribute(5, "GroupResult", g);
                    builder.AddAttribute(6, "Builder", builder);
                    builder.CloseComponent();
                }

                if (Group.GroupDescriptor.ShowFooter.GetValueOrDefault() && Columns.Where(c => c.GroupFooterTemplate != null).Any())
                {
                    builder.OpenComponent(7, typeof(RadzenDataGridGroupFooterRow<TItem>));
                    builder.AddAttribute(8, "Columns", Columns);
                    builder.AddAttribute(9, "Grid", Grid);
                    builder.AddAttribute(10, "GroupResult", GroupResult);
                    builder.AddAttribute(11, "Builder", builder);
                    builder.AddAttribute(12, "Parent", this);
                    builder.CloseComponent();
                }
            }
            else
            {
                if(!groupFootersOnly)
                {
                    int i = 0;
                    foreach(var item in GroupResult.Items)
                    {
                        builder.OpenComponent(0, typeof(RadzenDataGridRow<TItem>));
                        builder.AddAttribute(1, "Columns", Columns);
                        builder.AddAttribute(2, "Index", i);
                        builder.AddAttribute(3, "Grid", Grid);
                        builder.AddAttribute(4, "TItem", typeof(TItem));
                        builder.AddAttribute(5, "Item", item);
                        builder.AddAttribute(6, "InEditMode", Grid.IsRowInEditMode((TItem)item));

                        if (Grid.editContexts.ContainsKey((TItem)item))
                        {
                            builder.AddAttribute(7, nameof(RadzenDataGridRow<TItem>.EditContext), Grid.editContexts[(TItem)item]);
                        }

                        builder.CloseComponent();
                        i++;
                    }
                }

                if (Group.GroupDescriptor.ShowFooter.GetValueOrDefault(true) && Columns.Where(c => c.GroupFooterTemplate != null).Any())
                {
                    builder.OpenComponent(7, typeof(RadzenDataGridGroupFooterRow<TItem>));
                    builder.AddAttribute(8, "Columns", Columns);
                    builder.AddAttribute(9, "Grid", Grid);
                    builder.AddAttribute(10, "GroupResult", GroupResult);
                    builder.AddAttribute(11, "Builder", builder);
                    builder.AddAttribute(12, "Parent", this);
                    builder.CloseComponent();
                }
            }
        });
    }

    public Group Group { get; set; }

    int GetLevel()
    {
        int i = 0;
        var p = Parent;
        while(p != null)
        {
            p = p.Parent;
            i++;
        }

        return i;
    }

    private int CountVisibleLeafColumns<T>(RadzenDataGridColumn<TItem> column)
    {
        if (column.ColumnsCollection?.Count == 0)
        {
            return column.GetVisible()  ? 1 : 0;
        }

        int count = 0;
        foreach (var childColumn in column.ColumnsCollection)
        {
            count += CountVisibleLeafColumns<T>(childColumn);
        }
        return count;
    }
}
